#include "camera_rts.hh"

CameraRts::CameraRts (const Vector3f& pos, Window* w)
  : Camera (pos, w)
{
  teta = 89;
  radius_ = pos (0);
  forward_.val_set (0, 0, 1);
  up_.val_set (0, 0, -1);
}

CameraRts::~CameraRts ()
{}

void
CameraRts::move (const Vector3f& val)
{
  Vector3f front (0, 0, 1);
  Vector3f fwd = forward_ * (time_ / 20.0);
  Vector3f lft = left_ * (time_ / 20.0);

  target_ -= pos_;

  if (val (2) == 1)
    pos_ += fwd;
  else if (val (2) == -1)
    pos_ -= fwd;

  if (val (1) == 1)
    pos_ += lft;
  else if (val (1) == -1)
    pos_ -= lft;

  if (val (0) != 0)
    {
      phi -= val (0) * (time_ / 10.0);
      calc_vect ();
    }
  else
    target_ += pos_;
}

void
CameraRts::calc_vect ()
{
  if (teta > 89)
    teta = 89;
  else if (teta < 10)
    teta = 10;

  float r_temp = radius_;

  target_ += pos_;

  pos_ (2, -r_temp * cos (teta * M_PI / 180) * cos (phi * M_PI / 180) + target_ (2));
  pos_ (1, -r_temp * cos (teta * M_PI / 180) * sin (phi * M_PI / 180) + target_ (1));
  pos_ (0, r_temp * sin (teta * M_PI / 180) + target_ (0));

  Vector3f up;
  up.val_set (1, 0, 0);

  Vector3f le (target_ - pos_);
  le /= le.get_norme ();
  Vector3f tmp_le = le.vectorial (up);
  left_ = tmp_le;

  forward_ = up.vectorial (left_);

  forward_ /= forward_.get_norme ();
  left_ /= left_.get_norme ();

  up_ = le.vectorial (left_);
  up_ /= up_.get_norme ();
}

void
CameraRts::set_angles (float val_x, float val_y)
{
  (void) val_x;
  (void) val_y;
}

Vector3f*
CameraRts::get_3D_point (int x, int y)
{
  Vector3f vect_x = left_ * x_val;
  Vector3f vect_y = up_ * -y_val;

  Vector3f* res = new Vector3f (pos_);

  Vector3f fwd = target_ - pos_;
  fwd /= fwd.get_norme ();

  (*res) += fwd;

  (*res) += (vect_x * ((float) x) / 100.0);
  (*res) += (vect_y * ((float) y) / 100.0);

  return res;
}

void
CameraRts::scroll_up ()
{
  target_ -= pos_;

  teta -= 10;
  calc_vect ();
}

void
CameraRts::scroll_down ()
{
  target_ -= pos_;

  teta += 10;
  calc_vect ();
}
